package com.trela.paymeontime.web.services;

import java.math.BigDecimal;

import org.springframework.stereotype.Component;

import com.trela.paymeontime.web.model.Asset;
import com.trela.paymeontime.web.model.Occurence;
import com.trela.paymeontime.web.model.Payment;
import com.trela.paymeontime.web.model.PaymentItem;
import com.trela.paymeontime.web.model.PaymentType;
import com.trela.paymeontime.web.model.Priority;
import com.trela.paymeontime.web.model.UserSettings;
import com.trela.paymeontime.web.model.dto.BalanceInfo;
import com.trela.paymeontime.web.model.dto.PaymentContext;

@Component
public class BalanceCalculator {

    public void calculateAssets(PaymentContext context, UserSettings settings) {

        BalanceInfo balanceInfo = new BalanceInfo();
        balanceInfo.setBalanceDateTime(settings.getBalanceDateTime());

        BigDecimal currentAssets = BigDecimal.ZERO;
        BigDecimal currentAdditionalAssets = BigDecimal.ZERO;
        for (Asset asset : context.getAssets()) {
            if(Asset.AssetType.POSITIVE_ASSETS.contains(asset.getAssetType())){
                currentAssets = currentAssets.add(asset.getBalance());
            }else if(Asset.AssetType.NEGATIVE_ASSETS.contains(asset.getAssetType())){
                if(asset.getBalance().compareTo(BigDecimal.ZERO) > 0){
                    currentAdditionalAssets = currentAdditionalAssets.add(asset.getBalance());
                }
                if(!asset.getBalance().equals(asset.getLimit())){
                    Payment payment = new Payment(asset.getName()+" "+asset.getAssetType().toString(), asset.getLimit().subtract(asset.getBalance()), asset.getDueDateTime(),
                           PaymentType.OUTCOME, Occurence.SINGLE, Priority.MEDIUM);
                    PaymentItem paymentItem =new PaymentItem(payment , false, asset.getDueDateTime());
                    context.getPaymentItems().add(paymentItem);
                }
            }
        }
        balanceInfo.setCurrentAdditionalAssets(currentAdditionalAssets);
        balanceInfo.setCurrentAssets(currentAssets);
        balanceInfo.setCurrentAvailableAssets(currentAssets.add(currentAdditionalAssets));
        context.setBalanceInfo(balanceInfo);
    }

    public void calculateBalance(PaymentContext context, UserSettings settings) {
        BalanceInfo balanceInfo = context.getBalanceInfo();
        BigDecimal balance = balanceInfo.getCurrentAvailableAssets();
        
        for(PaymentItem paymentItem : context.getPaymentItems()){
            if(paymentItem.getDueDate().isBefore(settings.getBalanceDateTime())){
                if(PaymentType.INCOME.equals(paymentItem.getPayment().getType())){
                    balance = balance.add(paymentItem.getPayment().getValue());
                }else{
                    balance = balance.subtract(paymentItem.getPayment().getValue());    
                }
                
            }else{
                break;
            }
        }
        balanceInfo.setBalance(balance);
        
        if(balance.compareTo(BigDecimal.ZERO) <= 0 ){
            balanceInfo.setBalanceOverallState("danger");
        }else if(balance.compareTo(BigDecimal.valueOf(100)) <= 0 ){
            balanceInfo.setBalanceOverallState("warning");
        }else if(balance.compareTo(BigDecimal.valueOf(1000)) <= 0 ){
            balanceInfo.setBalanceOverallState("info");
        }else {
            balanceInfo.setBalanceOverallState("success");
        }
    }

}
